import Cookies from 'js-cookie'
import lodash from 'lodash'
// cookie保存的天数
import config from '@/config'
import { forEach, hasOneOf, objEqual } from '@/libs/tools'

export const TOKEN_KEY = 'token'

export const setToken = (token) => {
  Cookies.set(TOKEN_KEY, token, {expires: config.cookieExpires || 1})
}

export const getToken = () => {
  const token = Cookies.get(TOKEN_KEY)
  if (token) return token
  else return false
}

export const hasChild = (item) => {
  return item.children && item.children.length !== 0
}

const showThisMenuEle = (item, access) => {
  if (item.meta && item.meta.access && item.meta.access.length) {
    if (hasOneOf(item.meta.access, access)) return true
    else return false
  } else return true
}
/**
 * @param {Array} list 通过路由列表得到菜单列表
 * @returns {Array}
 */
export const getMenuByRouter = (list, access) => {
  let res = []
  forEach(list, item => {
    if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
      let obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: item.meta
      }
      if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, access)) {
        obj.children = getMenuByRouter(item.children, access)
      }
      if (item.meta && item.meta.href) obj.href = item.meta.href
      if (showThisMenuEle(item, access)) res.push(obj)
    }
  })
  return res
}

/**
 * @param {Array} routeMetched 当前路由metched
 * @returns {Array}
 */
export const getBreadCrumbList = (route, homeRoute) => {
  // let homeItem = { ...homeRoute, icon: homeRoute.meta.icon }
  let routeMetched = route.matched
  // if (routeMetched.some(item => item.name === homeRoute.name)) return [homeItem]
  let res = routeMetched.filter(item => {
    return item.meta === undefined || !item.meta.hide
  }).map(item => {
    let meta = {...item.meta}
    if (meta.title && typeof meta.title === 'function') meta.title = meta.title(route)
    let obj = {
      icon: (item.meta && item.meta.icon) || '',
      name: item.name,
      meta: meta,
      to: meta.to || ''
    }
    return obj
  })
  // res = res.filter(item => {
  //   return !item.meta.hideInMenu
  // })
  return [...res]
  // return [{...homeItem, to: homeRoute.path}, ...res]
}

export const getRouteTitleHandled = route => {
  let router = {...route}
  let meta = {...route.meta}
  if (meta.title && typeof meta.title === 'function') meta.title = meta.title(router)
  router.meta = meta
  return router
}

export const showTitle = (item, vm) => vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name)

/**
 * @description 本地存储和获取标签导航列表
 */
export const setTagNavListInLocalstorage = list => {
  localStorage.tagNaveList = JSON.stringify(list)
}
/**
 * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
 */
export const getTagNavListFromLocalstorage = () => {
  const list = localStorage.tagNaveList
  return list ? JSON.parse(list) : []
}

/**
 * @param {Array} routers 路由列表数组
 * @description 用于找到路由列表中name为home的对象
 */
export const getHomeRoute = (routers, homeName = 'project_list') => {
  let i = -1
  let len = routers.length
  let homeRoute = {}
  while (++i < len) {
    let item = routers[i]
    if (item.children && item.children.length) {
      let res = getHomeRoute(item.children, homeName)
      if (res.name) return res
    } else {
      if (item.name === homeName) homeRoute = item
    }
  }
  return homeRoute
}

/**
 * @param {*} list 现有标签导航列表
 * @param {*} newRoute 新添加的路由原信息对象
 * @description 如果该newRoute已经存在则不再添加
 */
export const getNewTagList = (list, newRoute) => {
  const { name, path, meta } = newRoute
  let newList = [...list]
  if (newList.findIndex(item => item.name === name) >= 0) return newList
  else newList.push({ name, path, meta })
  return newList
}

/**
 * @param {*} access 用户权限数组，如 ['super_admin', 'admin']
 * @param {*} route 路由列表
 */
const hasAccess = (access, route) => {
  if (route.meta && route.meta.access) return hasOneOf(access, route.meta.access)
  else return true
}

/**
 * 权鉴
 * @param {*} name 即将跳转的路由name
 * @param {*} access 用户权限数组
 * @param {*} routes 路由列表
 * @description 用户是否可跳转到该页
 */
export const canTurnTo = (name, access, routes) => {
  const routePermissionJudge = (list) => {
    return list.some(item => {
      if (item.children && item.children.length) {
        return routePermissionJudge(item.children)
      } else if (item.name === name) {
        return hasAccess(access, item)
      }
    })
  }
  return routePermissionJudge(routes)
}

/**
 * @param {String} url
 * @description 从URL中解析参数
 */
export const getParams = url => {
  const keyValueArr = url.split('?')[1].split('&')
  let paramObj = {}
  keyValueArr.forEach(item => {
    const keyValue = item.split('=')
    paramObj[keyValue[0]] = keyValue[1]
  })
  return paramObj
}

/**
 * @param {Array} list 标签列表
 * @param {String} name 当前关闭的标签的name
 */
export const getNextRoute = (list, route) => {
  let res = {}
  if (list.length === 2) {
    res = getHomeRoute(list)
  } else {
    const index = list.findIndex(item => routeEqual(item, route))
    console.log(route, index, list.length)
    if (index === list.length - 1) res = list[list.length - 2]
    else res = list[index + 1]
  }
  return res
}

/**
 * @param {Number} times 回调函数需要执行的次数
 * @param {Function} callback 回调函数
 */
export const doCustomTimes = (times, callback) => {
  let i = -1
  while (++i < times) {
    callback(i)
  }
}

export const findNodeUpper = (ele, tag) => {
  if (ele.parentNode) {
    if (ele.parentNode.tagName === tag.toUpperCase()) {
      return ele.parentNode
    } else {
      return findNodeUpper(ele.parentNode, tag)
    }
  }
}

export const findNodeUpperByClasses = (ele, classes) => {
  let parentNode = ele.parentNode
  if (parentNode) {
    let classList = parentNode.classList
    if (classList && classes.every(className => classList.contains(className))) {
      return parentNode
    } else {
      return findNodeUpperByClasses(parentNode, classes)
    }
  }
}

export const findNodeDownward = (ele, tag) => {
  const tagName = tag.toUpperCase()
  if (ele.childNodes.length) {
    let i = -1
    let len = ele.childNodes.length
    while (++i < len) {
      let child = ele.childNodes[i]
      if (child.tagName === tagName) return child
      else return findNodeDownward(child, tag)
    }
  }
}

export const showByAccess = (access, canViewAccess) => {
  return hasOneOf(canViewAccess, access)
}

/**
 * @description 根据name/params/query判断两个路由对象是否相等
 * @param {*} route1 路由对象
 * @param {*} route2 路由对象
 */
export const routeEqual = (route1, route2) => {
  const params1 = route1.params || {}
  const params2 = route2.params || {}
  const query1 = route1.query || {}
  const query2 = route2.query || {}
  return (route1.name === route2.name) && objEqual(params1, params2) && objEqual(query1, query2)
}

/**
 * 判断打开的标签列表里是否已存在这个新添加的路由对象
 */
export const routeHasExist = (tagNavList, routeItem) => {
  let len = tagNavList.length
  let res = false
  doCustomTimes(len, (index) => {
    if (routeEqual(tagNavList[index], routeItem)) res = true
  })
  return res
}

export const localSave = (key, value) => {
  localStorage.setItem(key, value)
}

export const localRead = (key) => {
  return localStorage.getItem(key) || ''
}

/**
 * 增删改调用接口状态提示
 * @param {self} [Object] 指向父级
 * @param {code} [Number] 接口返回状态码
 * @param {successText} [String] 成功提示文案
 * @param {errorText} [String] 失败提示文案
  */
export const showMessageTip = (self, code, successText, errorText) => {
  const sendType = code === 2000 ? 'success' : 'error'
  const content = code === 2000 ? successText : errorText
  self.$Message[sendType]({
    content,
    duration: 4
  })
}

/**
 * 根据子节点code,获取它对应的所有父级节点code 用于cascader回显
 * @param {jsonData} [Array] 遍历的json数据
 * @param {childCode} [String] 子节点code
 * return parentCodes [Array] 返回对应的所有父级code的数组
 */
export function getAllParentCodes (jsonData = [], childCode) {
  const codeArr = []
  const findParentCode = (data) => {
    if (!data || data.length < 1) {
      return []
    }
    data.forEach(item => {
      codeArr.push({
        code: item.value,
        parentCodes: typeof (item.parentId) === 'object' ? item.parentId : [item.parentId]
      })
      if (item.children && item.children.length > 0) {
        item.children.forEach(ele => {
          if (item.parentId) {
            ele.parentId = typeof (item.parentId) === 'object' ? item.parentId.concat(item.value) : [item.parentId].concat(item.value)
          } else {
            ele.parentId = [item.value]
          }
        })
        findParentCode(item.children)
      }
    })
  }
  findParentCode(JSON.parse(JSON.stringify(jsonData)))
  const result = codeArr.filter(item => item.code === childCode)
  return result.length ? result[0].parentCodes.concat(childCode) : [childCode]
}
/**
 * 给tree组件数据添加属性
 * @param {data} [Array] 传入json数据
 * @param {checkedCodes} [Array] 选中的codes
 * @param {propArray} [Array] 添加自定义key，用于级联组件 example:[{targetKey: 'id', hopeKey: 'value'}, {targetKey: 'name', hopeKey: 'label'}]
*/
export function addProp (treeData = [], checkedCodes = [], propArray = []) {
  const data = JSON.parse(JSON.stringify(treeData))
  const transform = (data, checkedCodes) => {
    data.forEach(item => {
      if (checkedCodes.length > 0 && checkedCodes.includes(item.id)) {
        item.checked = true
      }
      item.expand = true
      if (propArray) {
        propArray.forEach((prop) => {
          item[prop.hopeKey] = item[prop.targetKey]
        })
      }
      if (item.children && item.children.length) {
        transform(item.children, checkedCodes)
      }
    })
  }
  transform(data, checkedCodes)
  return data
}

// 获取随机数字
export const getRandomVal = () => {
  const mathRandomVal = Math.random().toString().split('.')[1]
  return lodash.uniqueId(mathRandomVal)
}

/**
 * 替换表达式中的变量,转换为map.get('var1')>10|map.get('var')<200|map.get('_var1')<500形式
 * @param {String} expressStr 表达式字符串
 */
export const replaceVar = (expressStr = '') => {
  // $&表示整个被匹配的字符串
  return expressStr.replace(/(([a-zA-Z].*?[0-9]?)|_)+/g, "processVariable.get('$&')")
}

/** 存储 DS_RESOURCE（用于决策流的数据、规则）
 *  @param {pathname} 项目pathname
 *  @param {targetKey} 目标key：ruleList--规则列表 outputList--输出数据列表
 *  @param {resourceList} 赋值目标
 */
export const setDsResource = (pathname, targetKey, resourceList) => {
  let DS_RESOURCE = sessionStorage.getItem('DS_RESOURCE')
  DS_RESOURCE = DS_RESOURCE ? JSON.parse(DS_RESOURCE) : {}
  if (DS_RESOURCE[pathname]) {
    DS_RESOURCE[pathname][targetKey] = resourceList
  } else {
    DS_RESOURCE[pathname] = {}
    DS_RESOURCE[pathname][targetKey] = resourceList
  }
  sessionStorage.setItem('DS_RESOURCE', JSON.stringify(DS_RESOURCE))
}

/**
 * 展平树形Array
 * @param {data} [Array] 源数据
 * @param {keys} [Array] 期望得到的key
 * @param {level} [Number] 层级
  */
export const flatten = (data, keys, level = 0) => {
  return data.reduce((arr, x) => [
    ...arr,
    // eslint-disable-next-line
    keys.reduce((o, k) => (o[k] = x[k], o), {level}),
    ...flatten(x.children || [], keys, level + 1)
  ], [])
}
